//
//  ChatView.swift
//  imprint
//
//  Created by 小柠檬🍋 on 2025/5/1.
//

import SwiftUI
import Kingfisher

struct ChatView: View {
    struct Param : Codable {
        var bean : AiRoleBean? = nil
        var isMain = false
    }
    
    @EnvironmentObject var userManager: UserManager
    @StateObject var viewModel = ChatViewModel()
    @State var text = ""
    @FocusState private var isFocused: Bool
    @State var showAi = false
    @State private var showDel = false //删除
    @State private var showEnd = false //结束
    @State private var itemEdit = false //item是否编辑
    @State private var showEmoji = false //是否显示表情
    @State private var showMore = false //是否显示更多
    @State private var showPat = false //拍一拍
    @State private var patAction = "拍一拍" //拍一拍
    @State private var patSuffix = "" //拍一拍后缀

    @State private var keyboardHeight: CGFloat = 0 //软键盘高度
    @State private var defaultKeyboardHeight: CGFloat = 280 //软键盘高度
    @State private var showPicker = false //选择图片选择框
    @State var maxPickerItems = 1
    @State var editWidth: CGFloat = 0 //输入框宽度

    var param : Param? = nil
    
    func isMain() -> Bool {
        return param?.isMain ?? false
    }
    
    func isBg() -> Bool {
        return viewModel.bgUrl?.isEmpty == false
    }
    
    private func onClickMore(type: ChatMoreType) {
        switch type {
        case .TYPE_END:
            showEnd = true
        case .TYPE_CLEAR:
            showDel = true
        case .TYPE_PICTURE:
            showPicker = true
        case .TYPE_TAKE_PHOTO:
            showLog("")
        case .TYPE_SEARCH:
            showLog("")
        case .TYPE_CHAT_SET:
            pathManager.jump(type: JumpType.AI_SET_VIEW, data: AiSetView.FromType.FROM_CHAT)
        case .TYPE_PAT:
            if !AppStorageManager.shared.checkChatFuncToggle() {
                return
            }
            showPat = true
        }
    }
    
    
    var body: some View {
        if isMain() {
            //首页的聊天无需要设置背景图，因为使用的是外部试图的背景图
            contentView
        } else {
            // 背景层
            if let bgUrl = viewModel.bgUrl {
                BackgroundView(url: bgUrl)
            }
            contentView
            //                .ignoresSafeArea(edges: .bottom) // 仅忽略底部安全区域,  键盘高度需要获取安全区域
                .navigationBarTitle("", displayMode: .inline)
            //                    .toolbarBackground(.visible, for: .navigationBar) // 确保背景可见
            //            .navigationBarBackButtonHidden(true) // 隐藏系统返回按钮
                .toolbar {
                    ToolbarItem(placement: .principal) {
                        // 放在导航栏中央
                        avatarView
                    }
                    ToolbarItem(placement: .navigationBarTrailing) {
                        //放在导航栏右边
                        ZStack {
                            Image(.mainIconChat)
                                .resizable()
                                .renderingMode(.template)
                                .scaledToFit()
                                .foregroundColor(themeManager.themeColor)
                                .frame(width: 23, height: 23)
                            Text(userManager.getAiCountStr(isShowCount: false))
                                .font(.system(size: 8))
                                .foregroundStyle(themeManager.themeColor)
                                .padding(.top,32)
                        }.padding(.top, -10)
                            .contentShape(Rectangle())
                            .onTapGesture {
                                pathManager.jump(type: JumpType.BUY_COUNT)
                            }
                    }
                }
        }
    }
    
}

extension ChatView {
    //头像信息
    var avatarView: some View {
        HStack{
            ZStack {
                //                KFImage(URL(string: viewModel.aiRole?.avatar.formatCdn() ?? ""))
                //                    .resizable()
                //                    .placeholder{
                //                        Image(.appDefaultLogo)
                //                            .resizable()
                //                            .scaledToFill()
                //                            .padding(EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10))
                //                            .frame(width: 40,height: 40)
                //                            .clipShape(Circle())
                //                    }
                //                    .background(Color.hex("515151").opacity(0.1))
                //                    .scaledToFill()
                //                    .frame(width: 40,height: 40)
                //                    .clipShape(Circle())
            }.contentShape(Rectangle())
                .onTapGesture {
                    viewModel.getAiRoleList()
                }
            Text(viewModel.aiRole?.name ?? "")
                .font(.system(size: 18,weight: .medium))
                .foregroundStyle(.bgNormalText)
        }
    }
}


extension ChatView {
    var contentView: some View {
        ZStack(alignment: .top) {
            ZStack(alignment: .top) {
                VStack(spacing: 0) {
                    chatView.background() {
                        if isMain() {
                            Color.clear
                                .opacityBg(isBg: isBg())
                        } else {
                            Color.bg
                                .opacityBg(isBg: isBg())
                        }
                        
                    }
                    if viewModel.choose {
                        chooseView
                    } else {
                        if iOS26() {
                            //26版本不要背景
                            sendView
                        } else {
                            sendView.background(.bgDialog.opacityBg(isBg: isBg()))
                        }
                        //底部,如果是弹起键盘，isMain不需要设置，不知道为啥自动被顶上去了
                        ZStack {
                            if showEmoji && !isFocused {
                                EmojiManagerView()
                            } else if showMore && !isFocused {
                                ChatMoreBottomView() { type in
                                    onClickMore(type: type)
                                }
                            }
                        }.frame(maxWidth: .infinity, maxHeight: (showEmoji || showMore) && !isFocused ? defaultKeyboardHeight : (isMain() ? 0 : keyboardHeight))
                            .background(.bgDialog.opacityBg(isBg: isBg()))
                    }
                }.background() {
                    if isMain() {
                        Color.clear.opacityBg(isBg: isBg())
                    } else {
                        Color.bgItem.opacityBg(isBg: isBg())
                    }
                }
                //ai 列表弹窗
                if showAi {
                    VStack {
                        aiListView
                        Spacer()
                    }.frame(maxHeight: .infinity)
                        .background(.black.opacity(0.3))
                        .transition(.opacity) // 只使用透明度过渡
                        .contentShape(Rectangle())
                        .onTapGesture {
                            showAi = false
                        }
                    
                }
                
            }.ignoresSafeArea(.keyboard) // 忽略键盘对视图布局的影响
                .frame(maxWidth: .infinity) // 水平充满可用空间
        }.onAppear() {
            if !viewModel.isInit{
                viewModel.aiRole = param?.bean
                viewModel.getData(false, true)
                viewModel.isInit = true
            } else {
                viewModel.scrollBottom = true
            }
        }.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in
            keyboardHeight = 0.01
        }.onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in
            let value = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
            keyboardHeight = (value?.height ?? 0) - (isMain() ? 85 : 0) //需要减去底部的高度
            if keyboardHeight < 0 {
                keyboardHeight = 0.01
            }
            defaultKeyboardHeight = keyboardHeight
            if isFocused {
                showEmoji = false
                showMore = false
            }
            showLog("keyboardHeight:\(keyboardHeight)")
            if !itemEdit { //非编辑item内容才行
                DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                    //键盘弹起来需要滚动到底部
                    viewModel.scrollBottom = true
                }
            }
            
        }.onReceive(viewModel.$aiItems.dropFirst()) { value in
            //ai列表加载成功，则直接弹窗
            if value.isEmpty == false {
                withAnimation {
                    showAi.toggle()
                }
            }
        }
        .onChange(of: BackupsManager.shared.backupsType) { newValue in
            //备份切换、需要重置
            viewModel.aiRole = nil
            viewModel.doReset()
        }
        .contentShape(Rectangle())
        .onTapGesture {
            // 点击空白区域隐藏键盘
            hideKeyboard()
            isFocused = false
            showEmoji = false
            showMore = false
        }
        .alert("温馨提示",isPresented:$showDel) {
            Button("取消",role: .cancel){}
            Button("确定",role: .destructive) {
                viewModel.clearChat()
            }
        } message: {
            Text("是否确定清空当前的角色的聊天记录")
        }
        .alert("温馨提示",isPresented:$showEnd) {
            Button("取消",role: .cancel){}
            Button("确定",role: .destructive) {
                viewModel.doAddChat(text: "结束话题", lastChatBean: viewModel.getLast(),target: nil, isEnd: true)
            }
        } message: {
            Text("是否结束话题")
        }.alert("你拍了拍\"\(viewModel.aiRole?.name ?? "")\"",isPresented:$showPat) {
            TextField("执行动作，如\"拍一拍\"", text: $patAction)
                .padding()
                .border(Color.gray, width: 1)
            TextField("(可选)输入后缀", text: $patSuffix)
                .padding()
                .border(Color.gray, width: 1)
            Button("取消",role: .cancel){}
            Button("确定",role: .destructive) {
                viewModel.doAddPat(mAction: patAction, suffixStr: patSuffix)
            }
        } message: {
            Text("")
        }.sheet(isPresented: $showPicker) {
            //选择图片，用于发送图片
            MediaPicker(
                selectionLimit: $maxPickerItems,
                maxFileSizeMB: 100, // 100MB
                filterType: MediaFilterType.images,
                isPresented: $showPicker,
                onComplete: { items in
                    showPicker = false
                    switch items.first?.type {
                    case .localImage(let uiImage):
                        viewModel.doAddPicture(image: uiImage, text: "")
                    case .networkImage(_, _, _):
                        showToast("图片读取错误")
                        break
                    case .localImagePath(_):
                        showToast("图片读取错误")
                        break
                    case .localVideo(_):
                        showToast("图片读取错误")
                        break
                    case .none:
                        showToast("图片读取错误")
                        break
                    }
                }
            )
        }
    }
}

extension ChatView {
    //聊天内容
    var chatView: some View {
        ZStack(alignment: .top) {
            ScrollViewReader { proxy in
                ScrollView {
                    //需要嵌套一层LazyVStack，不然会产生间距，而且大小还会随机
                    LazyVStack(spacing: 0) {
                        if !viewModel.isNoMore {
                            HStack{
                                ProgressView()
                                Text("加载中")
                                    .font(.system(size: 16))
                                    .foregroundStyle(.bgNormalText3)
                                    .padding()
                            }.id("TOP_ANCHOR")
                                .onAppear {
                                    if viewModel.allowMore {
                                        viewModel.getData(true, true)
                                    }
                                }
                        }
                        
                        if viewModel.isNoMore && BackupsManager.shared.backupsType == BackupsType.cloud {
                            ChatItemTipsView2(item: "鉴于聊天数据量庞大，官方备份不存储聊天信息，\n所有内容仅保存在本地设备上")
                        }
                        ForEach(Array(viewModel.items.enumerated()), id: \.element.objectId) { index, item in
                            let type = item.type
                            let contentType = item.contentType
                            if  IChatType.USER.rawValue == type &&
                                    (IChatContentType.TYPE_CONTENT.rawValue == contentType || IChatContentType.TYPE_CONTENT_TARGET.rawValue == contentType) &&
                                    item is ChatBean {
                                ChatItemUserView(viewModel: viewModel, item: item as! ChatBean) { clickEdit in
                                    withAnimation {
                                        //避免2个edit冲突问题
                                        itemEdit = clickEdit
                                    }
                                }.id(getId(item.objectId)).tag(getId(item.objectId)) // 确保每个元素都有唯一的 ID
                            } else if IChatType.BOT.rawValue == type &&
                                        (IChatContentType.TYPE_CONTENT.rawValue == contentType || IChatContentType.TYPE_CONTENT_TARGET.rawValue == contentType ||
                                         IChatContentType.TYPE_VOICE_MESSAGE.rawValue == contentType) &&
                                        item is ChatBean {
                                if let item = item as? ChatBean {
                                    ChatItemBotView(viewModel: viewModel, item: item) { clickEdit in
                                        withAnimation {
                                            //避免2个edit冲突问题
                                            itemEdit = clickEdit
                                        }
                                    }.id(getId(item.objectId)).tag(getId(item.objectId)) // 确保每个元素都有唯一的 ID

                                }
                               
                            } else if IChatType.USER.rawValue == type && (IChatContentType.TYPE_EMOJI_PICTURE.rawValue == contentType || IChatContentType.TYPE_PICTURE.rawValue == contentType) && item is ChatBean {
                                //用户表情包
                                ChatItemUserPictureView(viewModel: viewModel, item: item as! ChatBean)
                                    .id(getId(item.objectId)).tag(getId(item.objectId)) // 确保每个元素都有唯一的 ID
                            } else if IChatType.BOT.rawValue == type && (IChatContentType.TYPE_EMOJI_PICTURE.rawValue == contentType || IChatContentType.TYPE_PICTURE.rawValue == contentType) && item is ChatBean {
                                //ai表情包
                                ChatItemBotPictureView(viewModel: viewModel, item: item as! ChatBean)
                                    .id(getId(item.objectId)).tag(getId(item.objectId)) // 确保每个元素都有唯一的 ID
                            } else if IChatType.TIME.rawValue == type && item is ChatTimeBean {
                                ChatItemTimeView(item: item as! ChatTimeBean)
                                    .id(getId(item.objectId)).tag(getId(item.objectId)) // 确保每个元素都有唯一的 ID
                            } else if IChatContentType.TYPE_ACTION.rawValue == contentType {
                                ChatItemPatView(viewModel: viewModel, item: item as! ChatBean)
                                    .id(getId(item.objectId)).tag(getId(item.objectId)) // 确保每个元素都有唯一的 ID
                            }
                            else if IChatType.TIPS.rawValue == type && item is ChatTipsBean {
                                ChatItemTipsView(item: item as! ChatTipsBean)
                                    .id(getId(item.objectId)).tag(getId(item.objectId)) // 确保每个元素都有唯一的 ID
                            } else if IChatType.END.rawValue == type && item is ChatBean {
                                ChatItemEndView()
                                    .id(getId(item.objectId)).tag(getId(item.objectId)) // 确保每个元素都有唯一的 ID
                            } else {
                                Text("暂不支持此格式")
                                    .font(.system(size: 10))
                                    .foregroundStyle(.bgNormalText4)
                                    .id(getId(item.objectId)) // 确保每个元素都有唯一的 ID
                            }
                            
                        }
                        // 3. 添加一个底部锚点视图
                        Color.clear
                            .frame(height: 1)
                            .id("BOTTOM_ANCHOR") // 设置底部锚点 ID
                    }
                }.onReceive(viewModel.$loadTopId.dropFirst()) { value in
                    if value.isEmpty == false {
                        viewModel.loadTopId = ""
                        DispatchQueue.main.async {
                            showLog("滚动到指定：\(value)")
                            proxy.scrollTo(value, anchor: .top)
                        }
                        
                    }
                }.onReceive(viewModel.$scrollBottom.dropFirst()) { value in
                    if value == true {
                        // 当消息数组变化时，滚动到底部
                        viewModel.scrollBottom = false
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                            showLog("滚动底部")
                            proxy.scrollTo("BOTTOM_ANCHOR", anchor: .bottom)
                        }
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
                            //延迟，避免没有滚动彻底
                            showLog("滚动底部")
                            withAnimation {  // 可选：添加动画使滚动更自然
                                proxy.scrollTo("BOTTOM_ANCHOR", anchor: .bottom)
                            }
                        }
                        
                    }
                }.onReceive(viewModel.$scrollBottom2.dropFirst()) { value in
                    if value == true {
                        // 当消息数组变化时，滚动到底部
                        viewModel.scrollBottom2 = false
                        showLog("滚动底部")
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                            withAnimation {  // 可选：添加动画使滚动更自然
                                proxy.scrollTo("BOTTOM_ANCHOR", anchor: .bottom)
                            }
                        }
                    }
                }.onReceive(viewModel.$scrollChat.dropFirst()) { value in
                    if value.isEmpty == false {
                        viewModel.scrollChat = ""
                        showLog("滚动到指定位置")
                        DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                            withAnimation {  // 可选：添加动画使滚动更自然
                                proxy.scrollTo(getId(value), anchor: .bottom)
                            }
                        }
                    }
                }
            }
            
        }
    }
    
    func getId(_ value: String?) -> String {
        let id = "\(value ?? "")_\(viewModel.refreshId)"
//        showLog("id:\(id)")
//        return UUID().uuidString
        return id
    }
}

extension ChatView {
    //ai角色列表
    var aiListView: some View {
        VStack {
            ScrollView {
                //需要嵌套一层LazyVStack，不然会产生间距，而且大小还会随机
                LazyVStack(spacing: 0) {
                    ForEach(Array(viewModel.aiItems.enumerated()), id: \.element.objectId) { index, item in
                        ChatItemRoleView(item: item)
                            .contentShape(Rectangle())
                            .onTapGesture {
                                viewModel.aiRole = item
                                viewModel.doReset()
                                showAi = false
                            }
                    }
                }
            }
        }
        .frame(maxWidth: .infinity, maxHeight: 400)
        .background(.bgDialog)
    }
}

extension ChatView {

    //发送内容
    var sendView: some View {
        VStack(alignment: .leading) {
            HStack {
                ZStack(alignment: .leading) {
                    if text.isEmpty {
                        HStack{
                            Text("说点什么")
                                .foregroundColor(.gray)
                                .font(.system(size: 14))
                                .padding(.leading,3)
                        }
                    }
                    if !itemEdit {
                        TextEditor(text: $text)
                            .font(.system(size: 14))
                            .foregroundColor(.bgItemTitle)
                            .textFieldStyle(PlainTextFieldStyle())
                            .scrollContentBackground(.hidden)
                            .background(Color.clear)
                            .padding(.top,3)
                            .focused($isFocused)
                    }
                }
                .padding(.horizontal,10)
                .frame(height: 40)
                .frame(maxWidth: .infinity, alignment: .leading) // 使TextEditor内容左对齐
                .background {
                    if iOS26() && isMain() {
                        //由于26版本把最外一层背景隐藏掉了
                        Color.bgDialog.opacityBg(isBg : isBg(),0.5)
                    } else {
                        Color.bgEdit.opacityBg(isBg : isBg(),0.5)
                    }
                }
                .cornerRadius(5)
                .geiWidth(width: $editWidth)
                Image(.appIconEmoji)
                    .resizable()
                    .scaledToFit()
                    .foregroundColor(themeManager.themeColor)
                    .frame(width: 34, height: 33)
                    .onTapGesture {
                        withAnimation {
                            showMore = false
                            if isFocused == true {
                                showEmoji = true
                            } else {
                                showEmoji.toggle()
                            }
                        }
                        isFocused = false
                        
                    }
                if text.isEmpty == true {
                    //没有内容显示更多按钮
                    Image(.homeIconAdd2)
                        .resizable()
                        .renderingMode(.template)
                        .scaledToFit()
                        .foregroundColor(themeManager.themeColor)
                        .frame(width: 30, height: 30)
                        .clipShape(Circle())
                        .contentShape(Rectangle())
                        .onTapGesture {
                            withAnimation {
                                showEmoji = false
                                if isFocused == true {
                                    showMore = true
                                } else {
                                    showMore.toggle()
                                }
                            }
                            isFocused = false
                            
                        }
                } else {
                    Image(.homeIconGo)
                        .resizable()
                        .renderingMode(.template)
                        .scaledToFit()
                        .foregroundColor(themeManager.themeColor)
                        .frame(width: 30, height: 30)
                        .contentShape(Rectangle())
                        .onTapGesture {
                            viewModel.doAddChat(text: text, lastChatBean: viewModel.getLast(), target: viewModel.targetChatBean)
                            text = ""
                        }
                }
            }
            //引用内容
            if let target = viewModel.targetChatBean {
                ChatTargetView2(bean: target,width: editWidth) {
                    viewModel.targetChatBean = nil
                }.tag(target.objectId)

            }
        }.padding(.horizontal, 20)
            .padding(.vertical, 10)
    }
    
}

extension ChatView {
    //多选模式
    var chooseView: some View {
        HStack(alignment: .bottom) {
            Spacer()
            VStack{
                Image(.iconTrash)
                    .resizable()
                    .frame(width: 23,height: 23)
                Text("删除")
                    .font(.system(size: 12,weight: .medium))
                    .foregroundStyle(.bgItemContent)
            }.onTapGesture {
                showBtnDialog(text: "是否确定删除？", btn: "删除") {
                    viewModel.delChat()
                }
            }
            Spacer()
            VStack{
                Image(.iconCancel)
                    .resizable()
                    .frame(width: 23,height: 23)
                Text("取消")
                    .font(.system(size: 12,weight: .medium))
                    .foregroundStyle(.bgItemContent)
            }.onTapGesture {
                viewModel.cancelChooseMode()
            }
            Spacer()
        }.padding(.vertical, 10)
            .background(.bgDialog)
    }
}

extension ChatView {
    //判断是否是当前角色
    private func isCurAiRole(bean: ChatBean) -> Bool {
        return bean.aiUserId == viewModel.aiRole?.objectId || bean.role?.roleId == viewModel.aiRole?.objectId
    }
    
    //判断是否是当前角色
    private func isCurAiRole(id: String)-> Bool {
        return id == viewModel.aiRole?.objectId
    }
}

//#Preview {
//    ChatView()
//}


//定义预览提供者
struct ChatView_Previews: PreviewProvider {
    static var previews: some View {
        //使用预览共享配置
        configurePreviewEnvironment(for: ChatView())
    }
}
